/*
 * RadioButtonMenuItemDelegate.cpp  0.4.0 / Dec 05, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "RadioButtonMenuItemDelegate.h"

#include "QApplicationDelegate.h"
#include "QIconAdapter.h"

// RadioButtonMenuItemDelegate :: Protected Constructor. -----------------------

/*!
 * \brief Constructs new RadioButtonMenuItemDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the RadioButtonMenuItem java object
 */
RadioButtonMenuItemDelegate::RadioButtonMenuItemDelegate(JNIEnv *env,
                                                         jobject obj)
  : ActionComponentDelegate(env, obj), m_shortcut(0)
{
  // empty constructor body
}

// RadioButtonMenuItemDelegate :: Native Calls. --------------------------------

/*!
 * \brief Sets text
 *
 * \param env the JNIEnv pointer
 * \param text the text
 */
void RadioButtonMenuItemDelegate::setText(JNIEnv *env, jstring text)
{
  Q_ASSERT(env);
  Q_ASSERT(text);
  SWING_REENTRANT(setText, SWING_ENV_ARG, JSTRING_ARG(text))
  if (isQWidget()) {
    radioButton()->setText(QStringAdapter(env, text));
  } else {
    action()->setText(QStringAdapter(env, text));
  }
}

/*!
 * \brief Sets short cut.
 *
 * \param env the JNIEnv pointer
 * \param shortcut the shortcut
 */
void RadioButtonMenuItemDelegate::setShortcut(JNIEnv *env, jstring shortcut)
{
  Q_ASSERT(env);
  Q_ASSERT(shortcut);
  SWING_REENTRANT(setShortcut, SWING_ENV_ARG, JSTRING_ARG(shortcut))
  QStringAdapter shortcutString(env, shortcut);
  if (isQWidget()) {
    if (!m_shortcut) {
      m_shortcut = new QShortcut(widget());
    }
    if (shortcutString.isEmpty()) {
      m_shortcut->setKey(QKeySequence::UnknownKey);
    } else {
      m_shortcut->setKey(QKeySequence(shortcutString));
    }
  } else {
    if (shortcutString.isEmpty()) {
      action()->setShortcut(QKeySequence::UnknownKey);
    } else {
      action()->setShortcut(QKeySequence(shortcutString));
    }
  }
}

/*!
 * \brief Sets icon.
 *
 * \param env the JNIEnv pointer
 * \param iconSet the icon
 */
void RadioButtonMenuItemDelegate::setIcon(JNIEnv *env, jobject iconSet)
{
  Q_ASSERT(env);
  Q_ASSERT(iconSet);
  SWING_REENTRANT(setIcon, SWING_ENV_ARG, JOBJECT_ARG(iconSet))
  if (isQWidget()) {
    if (iconSet) {
      radioButton()->setIcon(QIconAdapter(env, iconSet));
    } else {
      radioButton()->setIcon(QIcon());
    }
  } else {
    if (iconSet) {
      action()->setIcon(QIconAdapter(env, iconSet));
    } else {
      action()->setIcon(QIcon());
    }
  }
}

/*!
 * \brief Sets whether or not the item is selected.
 *
 * \param env the JNIEnv pointer
 * \param selected \c true if selected
 */
void RadioButtonMenuItemDelegate::setSelected(JNIEnv *env, jboolean selected)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setSelected, SWING_ENV_ARG, JBOOLEAN_ARG(selected))
  if (isQWidget()) {
    radioButton()->setChecked(selected);
  } else {
    action()->setChecked(selected);
  }
}

// RadioButtonMenuItemDelegate :: Static Native Calls. -------------------------

/*!
 * \brief Initializes RadioButtonMenuItemDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the RadioButtonMenuItem java class
 *
 * \exception FatalError if failed
 */
void RadioButtonMenuItemDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT (!sm_selectedChangedMID);
  if (!INIT_UMID(selectedChanged, cls, "(IZ)V")) {
    FATAL_LOGGED_ERROR("RadioButtonMenuItemDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong RadioButtonMenuItemDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new RadioButtonMenuItemDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// RadioButtonMenuItemDelegate :: Native Callbacks. ----------------------------

/*!
 * \brief Calls \c selectedChanged method of the RadioButtonMenuItem object.
 *
 * \param modifiers the keyboard modifiers
 * \param selected \c true if the item is selected
 */
void RadioButtonMenuItemDelegate::selectedChanged(jint modifiers,
                                                  jboolean selected)
{
  jniObject()->callVoidMethod(sm_selectedChangedMID, modifiers, selected);
}

// RadioButtonMenuItemDelegate :: Protected Member Function. -------------------

/*!
 * \brief Toggled slot.
 *
 * \param checked \c true if the item is checked
 */
void RadioButtonMenuItemDelegate::toggledSlot(bool checked)
{
  selectedChanged(QApplicationDelegate::keyboardModifiers(), checked);
}

// RadioButtonMenuItemDelegate :: Overridden Member Functions. -----------------

/*!
 * \brief Creates QWidget adaptee.
 *
 * \return QWidget adaptee
 */
QWidget *RadioButtonMenuItemDelegate::createQWidget()
{
  QRadioButton *radioButton = new QRadioButton();
  radioButton->setAutoExclusive(false);
  connectDirect(radioButton, SIGNAL(toggled(bool)), SLOT(toggledSlot(bool)));
  return radioButton;
}

/*!
 * \brief Creates QAction adaptee.
 *
 * \return QAction adaptee
 */
QAction *RadioButtonMenuItemDelegate::createQAction()
{
  QAction *action = new QAction(this);
  action->setCheckable(true);
  m_actionGroup = new QActionGroup(this);
  action->setActionGroup(m_actionGroup);
  connectDirect(action, SIGNAL(toggled(bool)), SLOT(toggledSlot(bool)));
  return action;
}

/*!
 * \inheritDoc
 */
void RadioButtonMenuItemDelegate::deleteQWidget(QWidget *widget)
{
  if (m_shortcut) {
    delete m_shortcut;
    m_shortcut = 0;
  }
  connectDirect(widget, SIGNAL(toggled(bool)), SLOT(toggledSlot(bool)));
  ActionComponentDelegate::deleteQWidget(widget);
}

/*!
 * \inheritDoc
 */
void RadioButtonMenuItemDelegate::deleteQAction(QAction *action)
{
  disconnect(action, SIGNAL(toggled(bool)), SLOT(toggledSlot(bool)));
  ActionComponentDelegate::deleteQAction(action);
  delete m_actionGroup;
}

/*!
 * \inheritDoc
 */
QWidget *RadioButtonMenuItemDelegate::convertToQWidget(QAction *action)
{
  QRadioButton *radioButton = static_cast<QRadioButton *>(
                             ActionComponentDelegate::convertToQWidget(action));
  radioButton->setText(action->text());
  if (m_shortcut) {
    delete m_shortcut;
  }
  m_shortcut = new QShortcut(radioButton);
  m_shortcut->setKey(action->shortcut());
  radioButton->setChecked(action->isChecked());
  radioButton->setIcon(action->icon());
  return radioButton;
}

/*!
 * \inheritDoc
 */
QAction *RadioButtonMenuItemDelegate::convertToQAction(QWidget *widget)
{
  QRadioButton *radioButton = static_cast<QRadioButton *>(widget);
  QAction *action = ActionComponentDelegate::convertToQAction(radioButton);
  action->setText(radioButton->text());
  if (m_shortcut) {
    action->setShortcut(m_shortcut->key());
  }
  action->setChecked(radioButton->isChecked());
  action->setIcon(radioButton->icon());
  return action;
}

// RadioButtonMenuItemDelegate :: Private Static Data Member. ------------------

jmethodID RadioButtonMenuItemDelegate::sm_selectedChangedMID = 0;
